﻿using Fanuc.RobotInterface;
using IPlugin;
using IPlugin.Attributes;
using Mohe.Scada.Util.Helper;
using NLog;
using System.Net.Sockets;

namespace Fanuc.Robot
{
    [DriverInfo("FanucRobot", "1.0.0", "湖州精确科技有限公司")]
    public class FanucRobotDriver : IDriver
    {
        private static Logger _logger = LogManager.GetLogger(nameof(FanucRobotDriver));

        private readonly string _device;
        IExRobotIF _robot { get; } = new ExRobotIF(new RobotIF());
        public bool IsConnected => _robot.IsConnected;

        #region 配置参数
        [ConfigParameter("设备Id")]
        public int DeviceId { get; set; }


        [ConfigParameter("IP地址")]
        public string IpAddress { get; set; } = "127.0.0.1";

        [ConfigParameter("端口号")]
        public int Port { get; set; } = 9021;
        [ConfigParameter("超时时间ms")]
        public int TimeOut { get; set; } = 3000;

        [ConfigParameter("最小通讯周期ms")]
        public int MinPeriod { get; set; } = 1000;
        #endregion

        public FanucRobotDriver(string device)
        {
            _device = device;
            _logger.Info($"Device:[{_device}],Create()");
        }

        public bool Close()
        {
            try
            {
                _robot.Disconnect();
                _logger.Info($"Device:[{_device}],Close()");
                return true;
            }
            catch (Exception ex)
            {

                _logger.Error($"Device:{_device},Close Error {ex.Message}");
                return false;
            }

        }

        public bool Connect()
        {
            try
            {
                _logger.Info($"Device:[{_device}],Connect()");
                _robot.Connect(IpAddress, (ushort)Port, TimeOut);
                return true;
            }
            catch (Exception ex)
            {
                _logger.Error($"发那科机器人Device:[{_device}],Connect() Error", ex);
                return false;
            }
        }

        [Method("一次性读取DI")]
        public DriverReturnValueModel ReadDI(DriverAddressIoArgModel ioArg)
        {
            var ret = new DriverReturnValueModel { StatusType = EnumVariableStatus.Good };
            if (_robot != null && _robot.IsConnected)
            {
                ushort count = Convert.ToUInt16(ioArg.Address);
                var res = _robot.ReadDI(1, count);
                ret.Value = res.GetByteArrayFromBoolArray();
            }
            else
            {
                ret.StatusType = EnumVariableStatus.Bad;
                ret.Message = "连接失败";
            }
            return ret;
        }
        [Method("一次性读取DO")]
        public DriverReturnValueModel ReadDO(DriverAddressIoArgModel ioArg)
        {
            var ret = new DriverReturnValueModel { StatusType = EnumVariableStatus.Good };
            if (_robot != null && _robot.IsConnected)
            {
                ushort count = Convert.ToUInt16(ioArg.Address);
                var res = _robot.ReadDO(1, count);
                ret.Value = res.GetByteArrayFromBoolArray();
            }
            else
            {
                ret.StatusType = EnumVariableStatus.Bad;
                ret.Message = "连接失败";
            }
            return ret;
        }
        [Method("一次性读取GO")]
        public DriverReturnValueModel ReadGO(DriverAddressIoArgModel ioArg)
        {
            var ret = new DriverReturnValueModel { StatusType = EnumVariableStatus.Good };
            if (_robot != null && _robot.IsConnected)
            {
                ushort count = Convert.ToUInt16(ioArg.Address);
                ret.Value = _robot.ReadGO(1, count);
            }
            else
            {
                ret.StatusType = EnumVariableStatus.Bad;
                ret.Message = "连接失败";
            }
            return ret;

        }
        public DriverReturnValueModel Read(DriverAddressIoArgModel ioArg)
        {
            throw new NotImplementedException();
        }

        public Task<RpcResponse> WriteAsync(string RequestId, string Method, DriverAddressIoArgModel ioArg)
        {
            throw new NotImplementedException();
        }

        public void Dispose()
        {
            try
            {

                // Suppress finalization.
                GC.SuppressFinalize(this);

                _logger.Info($"Device:[{_device}],Dispose()");
            }
            catch (Exception ex)
            {
                _logger.Error($"Device:[{_device}],Dispose(),Error", ex);
            }

        }
    }
}
